/*
 * Copyright (C) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "imageknife_node_animator.h"

namespace ImageKnifePro {
void ImageKnifeNodeAnimator::RegisterAnimatorEvent()
{
    IMAGE_KNIFE_CHECK(option_ == nullptr);
    if (option_->onStart != nullptr) {
        GetNodeAPI()->registerNodeEvent(handle, NODE_IMAGE_ANIMATOR_EVENT_ON_START, 0, nullptr);
    }
    
    if (option_->onPause != nullptr) {
        GetNodeAPI()->registerNodeEvent(handle, NODE_IMAGE_ANIMATOR_EVENT_ON_PAUSE, 0, nullptr);
    }
    
    if (option_->onRepeat != nullptr) {
        GetNodeAPI()->registerNodeEvent(handle, NODE_IMAGE_ANIMATOR_EVENT_ON_REPEAT, 0, nullptr);
    }
    
    if (option_->onCancel != nullptr) {
        GetNodeAPI()->registerNodeEvent(handle, NODE_IMAGE_ANIMATOR_EVENT_ON_CANCEL, 0, nullptr);
    }
    
    if (option_->onFinish != nullptr) {
        GetNodeAPI()->registerNodeEvent(handle, NODE_IMAGE_ANIMATOR_EVENT_ON_FINISH, 0, nullptr);
    }
}

void ImageKnifeNodeAnimator::UnRegisterAnimatorEvent()
{
    IMAGE_KNIFE_CHECK(option_ == nullptr);
    if (option_->onStart != nullptr) {
        GetNodeAPI()->unregisterNodeEvent(handle, NODE_IMAGE_ANIMATOR_EVENT_ON_START);
    }

    if (option_->onPause != nullptr) {
        GetNodeAPI()->unregisterNodeEvent(handle, NODE_IMAGE_ANIMATOR_EVENT_ON_PAUSE);
    }

    if (option_->onRepeat != nullptr) {
        GetNodeAPI()->unregisterNodeEvent(handle, NODE_IMAGE_ANIMATOR_EVENT_ON_REPEAT);
    }

    if (option_->onCancel != nullptr) {
        GetNodeAPI()->unregisterNodeEvent(handle, NODE_IMAGE_ANIMATOR_EVENT_ON_CANCEL);
    }

    if (option_->onFinish != nullptr) {
        GetNodeAPI()->unregisterNodeEvent(handle, NODE_IMAGE_ANIMATOR_EVENT_ON_FINISH);
    }
}

void ImageKnifeNodeAnimator::RemoveDisplayedImage()
{
    GetNodeAPI()->resetAttribute(handle, NODE_IMAGE_ANIMATOR_IMAGES);
    imageData_ = nullptr;
}

void ImageKnifeNodeAnimator::OnDerivedNodeEvent(ArkUI_NodeEvent *event)
{
    IMAGE_KNIFE_CHECK(option_ == nullptr);
    auto eventType = OH_ArkUI_NodeEvent_GetEventType(event);
    std::function<void()> func = nullptr;

    switch (eventType) {
        case NODE_IMAGE_ANIMATOR_EVENT_ON_START :
            func = option_->onStart;
            break;
        case NODE_IMAGE_ANIMATOR_EVENT_ON_PAUSE :
            func = option_->onPause;
            break;
        case NODE_IMAGE_ANIMATOR_EVENT_ON_REPEAT :
            func = option_->onRepeat;
            break;
        case NODE_IMAGE_ANIMATOR_EVENT_ON_CANCEL :
            func = option_->onCancel;
            break;
        case NODE_IMAGE_ANIMATOR_EVENT_ON_FINISH :
            func = option_->onFinish;
            break;
        default: return;
    }

    if (func != nullptr) {
        func();
    }
}

void ImageKnifeNodeAnimator::UpdateAnimatorNodeEvent(std::shared_ptr<AnimatorOption> option)
{
    IMAGE_KNIFE_CHECK(option_ == nullptr);
    ArkUI_NodeHandle nodeHandle = handle;
    auto updateFunc = [nodeHandle](std::function<void()> originFunc, std::function<void()> newFunc,
                                   ArkUI_NodeEventType eventType) {
        if (newFunc == nullptr && originFunc != nullptr) {
            GetNodeAPI()->unregisterNodeEvent(nodeHandle, eventType);
        } else if (newFunc != nullptr && originFunc == nullptr) {
            GetNodeAPI()->registerNodeEvent(nodeHandle, eventType, 0, nullptr);
        }
    };

    updateFunc(option_->onStart, option->onStart, NODE_IMAGE_ANIMATOR_EVENT_ON_START);
    updateFunc(option_->onPause, option->onPause, NODE_IMAGE_ANIMATOR_EVENT_ON_PAUSE);
    updateFunc(option_->onRepeat, option->onRepeat, NODE_IMAGE_ANIMATOR_EVENT_ON_REPEAT);
    updateFunc(option_->onCancel, option->onCancel, NODE_IMAGE_ANIMATOR_EVENT_ON_CANCEL);
    updateFunc(option_->onFinish, option->onFinish, NODE_IMAGE_ANIMATOR_EVENT_ON_FINISH);
}

void ImageKnifeNodeAnimator::SetAnimatorAttribute()
{
    IMAGE_KNIFE_CHECK(option_ == nullptr);
    ArkUI_NumberValue value;
    // 保持与ArkTs的行为一致
    if (option_->state == ARKUI_ANIMATION_STATUS_INITIAL && option_->reverse == 1) {
        option_->state = ARKUI_ANIMATION_STATUS_STOPPED;
    }

    value = {.i32 = option_->state};
    ArkUI_AttributeItem item = {&value, 1};
    GetNodeAPI()->setAttribute(handle, NODE_IMAGE_ANIMATOR_STATE, &item);

    // NODE_IMAGE_ANIMATOR_DURATION
    value.i32 = option_->reverse;
    item = {&value, 1};
    GetNodeAPI()->setAttribute(handle, NODE_IMAGE_ANIMATOR_REVERSE, &item);

    value.i32 = option_->iterations;
    item = {&value, 1};
    GetNodeAPI()->setAttribute(handle, NODE_IMAGE_ANIMATOR_ITERATION, &item);
}

}

